﻿using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Media;
using System.Collections.Generic;
using System.Text;
using System.Security;

namespace ImaginationFactory
{
    //
    // 所有的特效都在类 ImageLibrary 中，
    // 其他地方需要调用特效则调用 ImageLibrary 的成员函数。
    // ImageLibrary 从 GDIPlusLibrary.dll 中导入函数
    //
    //
    public class ImageLibrary
    {
        //public ImageLibrary()
        //{
        //    GetABitmap = (GetABitmapDelegate)dll.Invoke( "GetABitmap", typeof( GetABitmapDelegate ) );
        //}

        ~ImageLibrary()
        {
            // 释放内存
            DeleteObject( currentHBitmap );
            for ( int i = 0; i < list.Count; i++ )
            {
                DeleteObject( list[ i ] );
            }
            list.Clear();
        }

        #region 变量

        IntPtr currentHBitmap;          // 保存当前图片的HBITMAP
        public IntPtr CurrentHBitmap
        {
            get
            {
                return currentHBitmap;
            }
        }

        List<IntPtr> list = new List<IntPtr>();
        int listIter = 0;

        // 保存从MyOpenFileDialog打开的图像的Image
        private System.Windows.Controls.Image loadedImage;// = new System.Windows.Controls.Image();
        public System.Windows.Controls.Image LoadedImage
        {
            get
            {
                return loadedImage;
            }
            set
            {
                loadedImage = value;
            }
        }

        // 当前打开文件的文件名
        private string filename;
        public string Filename
        {
            get
            {
                return filename;
            }
        }

        // 图像的实际高度
        private double height;
        public double Height
        {
            get
            {
                return height;
            }
        }

        // 图像的实际宽度
        private double width;
        public double Width
        {
            get
            {
                return width;
            }
        }

        #endregion

        #region DLL导入函数

        //public class DllInvoker
        //{

        //    [DllImport( "kernel32.dll" )]
        //    private extern static IntPtr LoadLibrary( String path );
        //    [DllImport( "kernel32.dll" )]
        //    private extern static IntPtr GetProcAddress( IntPtr lib, String funcName );
        //    [DllImport( "kernel32.dll" )]
        //    private extern static bool FreeLibrary( IntPtr lib );
        //    private IntPtr hLib;
        //    public DllInvoker( String DLLPath )
        //    {
        //        try
        //        {
        //            hLib = LoadLibrary( DLLPath );
        //        }
        //        catch (System.Exception ex)
        //        {
        //            MessageBox.Show( ex.ToString() );
        //        }
                
        //    }
        //    ~DllInvoker()
        //    {
        //        try
        //        {
        //            FreeLibrary( hLib );
        //        }
        //        catch (System.Exception ex)
        //        {
        //            MessageBox.Show( ex.ToString() );
        //        }
                
        //    }
        //    //将要执行的函数转换为委托
        //    public Delegate Invoke( String APIName, Type t )
        //    {
        //        IntPtr api = GetProcAddress( hLib, APIName );
        //        return (Delegate)Marshal.GetDelegateForFunctionPointer( api, t );
        //    }
        //}

        //   // public delegate int Compile(String command, StringBuilder inf);//编译
        //    public delegate IntPtr GetABitmapDelegate( [MarshalAs( UnmanagedType.LPWStr )] string strFileName );

        //    DllInvoker dll = new DllInvoker( "GDIPlusLibrary.dll" );
        //    GetABitmapDelegate GetABitmap;
            //Compile compile = (Compile)dll.Invoke("Compile", typeof(Compile));
            

        /*
         *  public delegate int Compile(String command, StringBuilder inf);//编译
            DllInvoke dll ＝ new DllInvoke(Server.MapPath(@"~/Bin/Judge.dll"));
            Compile compile = (Compile)dll.Invoke("Compile", typeof(Compile));
            StringBuilder inf;
            compile(@“gcc a.c -o a.exe“,inf); //这里就是调用我的DLL里定义的Compile函数
         * 
         */

        //[sysimport( dll="user32.dll" )]   

        //
        // DLLImport Functions
        //
        [DllImport( "gdi32.dll", CharSet=CharSet.Auto ) ]
        public static extern IntPtr DeleteObject( IntPtr hobj );

        [DllImport( "GDIPlusLibrary.dll", EntryPoint="GetABitmap", CharSet=CharSet.Unicode )]
        public static extern IntPtr GetABitmap( [MarshalAs( UnmanagedType.LPWStr )] string strFileName );

        //
        // 从DLL导入图像处理函数
        //
        //
        [DllImport( "GDIPlusLibrary.dll", EntryPoint="ImageEffects" )]
        public static extern IntPtr ImageEffects( IntPtr bitmap, ref Parameter param );

        //
        // 从DLL导入保存图像函数
        //
        //
        [DllImport( "GDIPlusLibrary.dll", EntryPoint="SavePicture" )]
        public static extern int SavePicture( IntPtr bitmap,
            [MarshalAs( UnmanagedType.LPWStr )] string strFileName,
            PictureFileType type );

        #endregion

        #region 图像处理准备工作

        //
        // 打开文件的对话框，将打开的图片的HBITMAP保存在currentHBitmap中
        //
        //
        public bool MyOpenFileDialog()
        {
            System.Windows.Forms.OpenFileDialog dialog = new System.Windows.Forms.OpenFileDialog();
            dialog.Title = "Load an image...";
            dialog.Multiselect = false;                


            if ( dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK )
            {
                try
                {
                    LoadImage( dialog.FileName );

                    return true;
                }
                catch ( Exception er )
                {
                    MessageBox.Show( er.ToString() );
                    return false;
                }
            }
            else
            {
                return false;
            }            
        }


        // 备份的内存占用
        const int maxMemorySize = 50000000;    // 约 100 MB，没有考虑压缩的图像
        int numBackup = 0;                      // 备份图片的张数

        //
        // 打开图片
        //
        //
        public void LoadImage( string name )
        {
            try
            {
                // 删除缓存的图片
                for ( int i = 0; i < list.Count; i++ )
                {
                    DeleteObject( list[ i ] );
                }
                list.Clear();
                listIter = 0;

                // 从DLL的函数中读取HBITMAP
                currentHBitmap = GetABitmap( name );
                filename = name; // 记录文件名
                list.Add( currentHBitmap ); // 加入链表中

                // 从GDI转换成GDI+
                System.Drawing.Bitmap m_bitmap = System.Drawing.Bitmap.FromHbitmap( currentHBitmap );
                this.width = m_bitmap.Width;
                this.height = m_bitmap.Height;
                m_bitmap.Dispose();

                // 计算备份的图片的张数
                numBackup = maxMemorySize / (int)width / (int)height;

                loadedImage = new System.Windows.Controls.Image();
                // 从GDI+的Bitmap转换成WPF的Image
                loadedImage.Source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                    currentHBitmap,
                    IntPtr.Zero,
                    Int32Rect.Empty,
                    System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions() );
                // 设置图像保持长宽比显示
                loadedImage.Stretch = Stretch.Uniform;
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }

        }

        //
        // 打开图片，保存图片GDI指针，记录图片长宽
        //
        //
        public void LoadImageForThread( string name )
        {
            try
            { 
                // 从DLL的函数中读取HBITMAP
                currentHBitmap = GetABitmap( name );
                filename = name; // 记录文件名               

                // 从GDI转换成GDI+
                System.Drawing.Bitmap m_bitmap = System.Drawing.Bitmap.FromHbitmap( currentHBitmap );
                this.width = m_bitmap.Width;
                this.height = m_bitmap.Height;
                m_bitmap.Dispose();
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }
        }




        //
        // 保存文件的对话框
        //
        //
        public void MySaveFileDialog()
        {
            System.Windows.Forms.SaveFileDialog dialog = new System.Windows.Forms.SaveFileDialog();
            dialog.Title = "保存图像";
            dialog.Filter = "JPG File(*.jpg)|*.JPG|BMP File(*.bmp)|*.BMP|All files (*.*)|*.*";

            if ( dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK )
            {
                try
                {
                    if ( dialog.FileName.ToLower().EndsWith( "jpg" ) )
                    {
                        SavePicture( currentHBitmap, dialog.FileName, PictureFileType.FileType_JPEG );
                    }
                    else if ( dialog.FileName.ToLower().EndsWith( "bmp" ) )
                    {
                        SavePicture( currentHBitmap, dialog.FileName, PictureFileType.FileType_BMP );
                    }
                }
                catch ( System.Exception ex )
                {
                    MessageBox.Show( ex.ToString() );
                }
            }
        }



        //
        // 将HBITMAP类型的hBitmap装换成Bitmap并保存在全局变量loadedIamge中，
        // 最后释放内存hBitmap。
        //
        //
        private void HBITMAP2Bitmap( IntPtr hBitmap )
        {
            try
            {
                // 将HBITMAP转化成Bitmap
                System.Drawing.Bitmap bitmap = System.Drawing.Bitmap.FromHbitmap( hBitmap );

                // 记录图片的长宽
                this.width = bitmap.Width;
                this.height = bitmap.Height;


                // 转为WPF图片显示类型
                loadedImage = new System.Windows.Controls.Image();
                loadedImage.Source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                    hBitmap,
                    IntPtr.Zero,
                    Int32Rect.Empty,
                    System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions() );
                loadedImage.Stretch = System.Windows.Media.Stretch.Uniform;

                // 释放内存，并将hBitmap赋值给currentHBitmap
                bitmap.Dispose();
                //DeleteObject( currentHBitmap );

                currentHBitmap = hBitmap;

                
                // 备份以便于撤销
                
                if ( list.Count > numBackup )  // 大于缓存的话
                {
                    DeleteObject( list[ 0 ] );
                    list.RemoveAt( 0 );
                }
                else if ( list.Count > 0 && listIter != list.Count - 1 )   // 重做后，从重做点往后删除缓存
                {
                    int i = list.Count - 1;
                    do
                    {
                        DeleteObject( list[ i ] );
                        list.RemoveAt( i );
                    } while ( i >= 0 && --i != listIter );
                }

                list.Add( hBitmap ); // 加入链表中      
                listIter = list.Count - 1;
            }
            catch ( Exception e )
            {
                MessageBox.Show( e.ToString() );
            }
        }

        public void Undo()
        {
            try
            {
                if ( list.Count > 0 && listIter > 0 )
                {
                    currentHBitmap = list[ --listIter ];

                    // 将HBITMAP转化成Bitmap
                    System.Drawing.Bitmap bitmap = System.Drawing.Bitmap.FromHbitmap( currentHBitmap );
                    // 记录图片的长宽
                    this.width = bitmap.Width;
                    this.height = bitmap.Height;

                    loadedImage = new System.Windows.Controls.Image();

                    loadedImage.Source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                        currentHBitmap,
                        IntPtr.Zero,
                        Int32Rect.Empty,
                        System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions() );

                    loadedImage.Stretch = System.Windows.Media.Stretch.Uniform;
                }
            }
            catch ( Exception e )
            {
                MessageBox.Show( e.ToString() );
            }
        }

        public void Redo()
        {
            try
            {
                if ( list.Count > 0 )
                {
                    currentHBitmap = list[ listIter >= list.Count - 1 ? list.Count - 1 : ++listIter ];

                    // 将HBITMAP转化成Bitmap
                    System.Drawing.Bitmap bitmap = System.Drawing.Bitmap.FromHbitmap( currentHBitmap );
                    // 记录图片的长宽
                    this.width = bitmap.Width;
                    this.height = bitmap.Height;

                    loadedImage = new System.Windows.Controls.Image();

                    loadedImage.Source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                        currentHBitmap,
                        IntPtr.Zero,
                        Int32Rect.Empty,
                        System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions() );

                    loadedImage.Stretch = System.Windows.Media.Stretch.Uniform;
                }
            }
            catch ( Exception e )
            {
                MessageBox.Show( e.ToString() );
            }
        }

        #endregion

        #region 图像处理

        //
        // 反色
        //
        //
        public void InvertColors()
        {
            try
            {
                // 设置效果
                Parameter param = new Parameter();
                param.m_Kind = KindOfEffect.Inverse_Color_image;

                // 从DLL的函数中读取处理好的HBITMAP
                IntPtr hBitmap = ImageEffects( currentHBitmap, ref param );

                HBITMAP2Bitmap( hBitmap );               
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }
        }

        //
        // 提供左右镜像和上下镜像
        //
        //
        public void MirrorEffect( Mirror_Sign sign )
        {
            try
            {
                // 设置效果
                Parameter param = new Parameter();
                param.m_Kind = KindOfEffect.Mirror_image;
                param.mirror_Sign = sign;

                // 从DLL的函数中读取处理好的HBITMAP
                IntPtr hBitmap = ImageEffects( currentHBitmap, ref param );

                HBITMAP2Bitmap( hBitmap );
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }
        }

        // 
        // 裁剪
        //
        //
        public void CutOutImage( Point startPoint, Point endPoint )
        {
            try
            {
                // 设置效果
                Parameter param = new Parameter();
                param.m_Kind = KindOfEffect.CutOut_image;
                param.x1 = (int)startPoint.X;
                param.y1 = (int)startPoint.Y;
                param.x2 = (int)endPoint.X;
                param.y2 = (int)endPoint.Y;

                this.width = Math.Abs( param.x1 -  param.x2 );
                this.height = Math.Abs( param.y1 -  param.y2 );

                // 从DLL的函数中读取处理好的HBITMAP
                IntPtr hBitmap = ImageEffects( currentHBitmap, ref param );

                HBITMAP2Bitmap( hBitmap );
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }
        }

        // 
        // 旋转
        //
        //
        public void RotateImage( int angel )
        {
            try
            {
                // 设置效果
                Parameter param = new Parameter();
                param.m_Kind = KindOfEffect.Rotate_image;
                param.m_Angle = angel;

                // 从DLL的函数中读取处理好的HBITMAP
                IntPtr hBitmap = ImageEffects( currentHBitmap, ref param );

                HBITMAP2Bitmap( hBitmap );
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }
        }

        // 
        // 放缩
        //
        //
        public void ScaleImage( double xRate, double yRate )
        {
            try
            {
                // 设置效果
                Parameter param = new Parameter();
                param.m_Kind = KindOfEffect.Scale_image;
                param.Scale_x = xRate;
                param.Scale_y = yRate;

                // 从DLL的函数中读取处理好的HBITMAP
                IntPtr hBitmap = ImageEffects( currentHBitmap, ref param );

                HBITMAP2Bitmap( hBitmap );
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }
        }

        //
        // 单色
        //
        //
        public void SingleColor( BlackAndWhite sign )
        {
            try
            {
                // 设置效果
                Parameter param = new Parameter();
                param.m_Kind = KindOfEffect.BlackAndWhite_image;
                param.blackandwhite = sign;

                // 从DLL的函数中读取处理好的HBITMAP
                IntPtr hBitmap = ImageEffects( currentHBitmap, ref param );

                HBITMAP2Bitmap( hBitmap );
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }
        }

        //
        // 明暗度
        //
        //
        public void IntensityAdjustment( int pecent )
        {
            try
            {
                // 设置效果
                Parameter param = new Parameter();
                param.m_Kind = KindOfEffect.Light_Shade_image;
                param.Light_Shade = pecent;

                // 从DLL的函数中读取处理好的HBITMAP
                IntPtr hBitmap = ImageEffects( currentHBitmap, ref param );

                HBITMAP2Bitmap( hBitmap );
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }
        }


        //
        // 通道混合器
        //
        //
        public void ChannelMixer( ColorPassage channel, double value )
        {
            try
            {
                // 设置效果
                Parameter param = new Parameter();
                param.m_Kind = KindOfEffect.Color_Passage_image;
                param.colorpassage = channel;
                param.ColorPassage_blue = 0;
                param.ColorPassage_green = 0;
                param.ColorPassage_red = 0;

                switch ( param.colorpassage )
                {
                    case ColorPassage.ColorPassage_blue:
                        param.ColorPassage_blue = value;
                        break;
                    case ColorPassage.ColorPassage_green:
                        param.ColorPassage_green = value;
                        break;
                    case ColorPassage.ColorPassage_red:
                        param.ColorPassage_red = value;
                        break;
                }

                // 从DLL的函数中读取处理好的HBITMAP
                IntPtr hBitmap = ImageEffects( currentHBitmap, ref param );

                HBITMAP2Bitmap( hBitmap );
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }
        }

        //
        // 高斯模糊
        //
        //
        public void GussianBlur( int guassianMatrixSize = 5, int guassianPower = 5 )
        {
            try
            {
                // 设置效果
                Parameter param = new Parameter();
                param.m_Kind = KindOfEffect.GussianBlur_image;
                param.m_GuassianMatrixSize = guassianMatrixSize;
                param.m_GuassianPower = guassianPower;

                // 从DLL的函数中读取处理好的HBITMAP
                IntPtr hBitmap = ImageEffects( currentHBitmap, ref param );

                HBITMAP2Bitmap( hBitmap );
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }
        }

        //
        // 直方图均衡化
        //
        //
        public void GT_Equal()
        {
            try
            {
                // 设置效果
                Parameter param = new Parameter();
                param.m_Kind = KindOfEffect.GT_Equal_image;

                // 从DLL的函数中读取处理好的HBITMAP
                IntPtr hBitmap = ImageEffects( currentHBitmap, ref param );

                HBITMAP2Bitmap( hBitmap );
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }
        }

        //
        // 对比度
        //
        //
        public void ColorConstrast( double contrastValue = 1.1f )
        {
            try
            {
                // 设置效果
                Parameter param = new Parameter();
                param.m_Kind = KindOfEffect.ColorContrats_image;
                param.m_ConstrastValue = contrastValue;

                // 从DLL的函数中读取处理好的HBITMAP
                IntPtr hBitmap = ImageEffects( currentHBitmap, ref param );

                HBITMAP2Bitmap( hBitmap );
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }
        }

        //
        // 二值化
        //
        //
        public void Threshold( int thres = 128 )
        {
            try
            {
                // 设置效果
                Parameter param = new Parameter();
                param.m_Kind = KindOfEffect.Threshold_image;
                param.m_ThresHold = thres;

                // 从DLL的函数中读取处理好的HBITMAP
                IntPtr hBitmap = ImageEffects( currentHBitmap, ref param );

                HBITMAP2Bitmap( hBitmap );
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }
        }


        //
        // 腐蚀
        //
        //
        public void Erosion()
        {
            try
            {
                // 设置效果
                Parameter param = new Parameter();
                param.m_Kind = KindOfEffect.Erosion_image;

                // 从DLL的函数中读取处理好的HBITMAP
                IntPtr hBitmap = ImageEffects( currentHBitmap, ref param );

                HBITMAP2Bitmap( hBitmap );
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }
        }

        //
        // 膨胀
        //
        //
        public void Dilation()
        {
            try
            {
                // 设置效果
                Parameter param = new Parameter();
                param.m_Kind = KindOfEffect.Dilation_image;

                // 从DLL的函数中读取处理好的HBITMAP
                IntPtr hBitmap = ImageEffects( currentHBitmap, ref param );

                HBITMAP2Bitmap( hBitmap );
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }
        }

        //
        // 内边缘
        //
        //
        public void InnerEdge()
        {
            try
            {
                // 设置效果
                Parameter param = new Parameter();
                param.m_Kind = KindOfEffect.InnerEdge_image;

                // 从DLL的函数中读取处理好的HBITMAP
                IntPtr hBitmap = ImageEffects( currentHBitmap, ref param );

                HBITMAP2Bitmap( hBitmap );
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }
        }

        //
        // 素描画
        //
        //
        public void Laplacian()
        {
            try
            {
                // 设置效果
                Parameter param = new Parameter();
                param.m_Kind = KindOfEffect.Laplacian_image;

                // 从DLL的函数中读取处理好的HBITMAP
                IntPtr hBitmap = ImageEffects( currentHBitmap, ref param );

                HBITMAP2Bitmap( hBitmap );
            }
            catch ( Exception er )
            {
                MessageBox.Show( er.ToString() );
            }
        }

        #endregion
    }
}
